﻿




using System;
using System.Collections.Generic;
using System.Linq;
using Hotpot.Infrastructure;
using Hotpot.Models;
using Hotpot.Modules.CMS.Models;

namespace Hotpot.Modules.CMS.Repositories.SqlServer
{
    public class SqlServerPageRepository : IPageRepository
    {
        private readonly HotpotCMSDataContext context;
        private readonly Guid siteID;

        public SqlServerPageRepository(HotpotCMSDataContext context, HotpotContext hotpotContext)
        {
            this.context = context;
            siteID = hotpotContext.Site.ID;
        }

        #region IPageRepository Members

        public Page GetPage(string slug)
        {
            IQueryable<hotpot_CMS_Page> query =
                from p in context.hotpot_CMS_Pages
                where p.SiteID == siteID && string.Compare(p.Slug, slug, true) == 0
                select p;

            return projectPages(query).FirstOrDefault();
        }

        public IEnumerable<Page> GetPages()
        {
            var query =
                from p in context.hotpot_CMS_Pages
                where p.SiteID == siteID
                select p;

            return projectPages(query).ToArray();
        }

        public Page Save(Page page)
        {
            hotpot_CMS_Page pageToSave = null;

            if (page.ID != Guid.Empty)
                pageToSave = context.hotpot_CMS_Pages.FirstOrDefault(p => p.SiteID == page.Site.ID && p.PageID == page.ID);

            if (pageToSave == null)
            {
                pageToSave = new hotpot_CMS_Page();

                pageToSave.SiteID = page.Site.ID;
                pageToSave.PageID = page.ID != Guid.Empty ? page.ID : Guid.NewGuid();

                context.hotpot_CMS_Pages.InsertOnSubmit(pageToSave);
            }

            pageToSave.TemplateName = page.TemplateName ?? "";
            pageToSave.Title = page.Title ?? "";
            pageToSave.Description = page.Description ?? "";
            pageToSave.Slug = page.Slug;
            pageToSave.PublishedDate = page.Published;

            context.SubmitChanges();

            return GetPage(pageToSave.Slug);
        }

        public bool Remove(Page page)
        {
            return false;

            //hotpot_Page foundPage = context.hotpot_Pages.FirstOrDefault(p => p.PageID == pageID);
            //bool removedPage = false;

            //if (foundPage != null)
            //{
            //    foundPage.State = (byte)EntityState.Removed;

            //    context.SubmitChanges();

            //    removedPage = true;
            //}

            //return removedPage;
        }

        public ContentItem GetContentItem(Page page, string name)
        {
            return GetContentItem(context, siteID, page, name);
        }

        public IEnumerable<ContentItem> GetContentItems(Guid pageID)
        {
            return (
                from ci in context.hotpot_CMS_ContentItems
                group ci.Version by new { ContentItemName = ci.ContentItemName, PageIDHasValue = ci.PageID.HasValue, PageIDValue = ci.PageID.Value } into results
                join ci in context.hotpot_CMS_ContentItems on new { ContentItemName = results.Key.ContentItemName, PageIDHasValue = results.Key.PageIDHasValue, PageIDValue = results.Key.PageIDValue, Version = results.Max() } equals new { ContentItemName = ci.ContentItemName, PageIDHasValue = ci.PageID.HasValue, PageIDValue = ci.PageID.Value, Version = ci.Version }
                where ci.SiteID == siteID && ci.PageID == pageID
                select SqlServerContentItemRepository.ProjectContentItem(context, ci)
                ).ToArray();
        }

        public ContentItem Save(ContentItem contentItem)
        {
            return SqlServerContentItemRepository.SaveContentItem(context, contentItem);
        }

        #endregion

        #region Static Methods

        public static ContentItem GetContentItem(HotpotCMSDataContext context, Guid siteID, Page page, string name)
        {
            return (
                from ci in context.hotpot_CMS_ContentItems
                where ci.SiteID == siteID && ci.PageID == page.ID && string.Compare(ci.ContentItemName, name, true) == 0
                select SqlServerContentItemRepository.ProjectContentItem(context, ci)
                ).FirstOrDefault();
        }

        #endregion

        #region Private Methods

        private IEnumerable<Page> projectPages(IQueryable<hotpot_CMS_Page> pages)
        {
            return (
                from p in pages
                let ci = GetContentItems(p.PageID)
                select new Page(p.PageID, new SiteSmall(p.SiteID), p.TemplateName, p.Title, p.Description, p.Slug, p.PublishedDate)
                ).ToArray();
        }

        #endregion
    }
}
